package tp.pr4.instructions;

import tp.pr4.Message;
import tp.pr4.NavigationModule;
import tp.pr4.RobotEngine;
import tp.pr4.instructions.exceptions.*;
import tp.pr4.items.Item;
import tp.pr4.items.ItemContainer;

public class OperateInstruction implements Instruction {

	public OperateInstruction() {
		this.id = "";
	}

	public OperateInstruction(String cad) {
		this.id = cad;
	}

	/**
	 * Parses the String returning an instance of OperateInstruction or throwing
	 * a WrongInstructionFormatException()
	 * 
	 * @param cad
	 *            - text String to parse
	 * @return Instruction Reference to an instance of OperateInstruction
	 */
	public Instruction parse(String cad) throws WrongInstructionFormatException {
		String words[] = cad.split(" ");
		if (words.length != 2)
			throw new WrongInstructionFormatException(Message.NOT_UNDERSTAND);
		for (String i : Message.OPERATE_INSTRUCTION) {
			if (words[0].equalsIgnoreCase(i))
				return new OperateInstruction(words[1]);
		}
		throw new WrongInstructionFormatException(Message.NOT_UNDERSTAND);
	} // puede que haya que cambiar el mensaje de la excepcion

	@Override
	/**
	 * Returns a description of the Instruction syntax. The string does not end with the line separator. It is up to the caller adding it before printing.
	 */
	public String getHelp() {
		String help = Message.OPERATE_INSTRUCTION[0];
		for (int i = 1; i < Message.OPERATE_INSTRUCTION.length; i++)
			help += "|" + Message.OPERATE_INSTRUCTION[i];
		help += " <ID>";
		return help;
	}

	/**
	 * Set the execution context. The method receives the entire engine (engine,
	 * navigation and the robot container) even though the actual implementation
	 * of execute() may not require it.
	 * 
	 * @param engine
	 *            - The robot engine
	 * @param navigation
	 *            - The information about the game, i.e., the places, current
	 *            direction and current heading to navigate
	 * @param robotContainer
	 *            - The inventory of the robot
	 */
	public void configureContext(RobotEngine engine,
			NavigationModule navigation, ItemContainer robotContainer) {
		this.engine = engine;
		this.navigation = navigation;
		this.robotContainer = robotContainer;
	}

	/**
	 * The robot uses the requested item.
	 * 
	 * @throws InstructionExecutionException
	 *             - When the robot inventory does not contain an item with this
	 *             name or when the item cannot be used
	 */
	public void execute() throws InstructionExecutionException {
		Item item = this.robotContainer.getItem(this.id);
		if (item == null)
			throw new InstructionExecutionException(Message.NO_ITEM.replace(
					"<id>", this.id));
		else if (!item.use(engine, navigation))
			throw new InstructionExecutionException(
					Message.ITEM_PROBLEMS.replace("<id>", item.getId()));
		else {

			if (!item.canBeUsed()) {

				this.robotContainer.pickItem(item.getId());
				System.out.println(Message.NO_MORE_ITEM.replace("<id>",
						item.getId()));
			}
		}
	}

	private RobotEngine engine;
	private NavigationModule navigation;
	private ItemContainer robotContainer;
	private String id;
}
